﻿namespace MovieGalleryDLL
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using DataAdapters = MovieGalleryDLL.DataBase.MovieDataSetTableAdapters;
    using System.Text.RegularExpressions;
    using System.Collections;
    using Database = MovieGalleryDLL.DataBase;
using System.ComponentModel;
    using System.Threading.Tasks;

    public class Scanner
    {
        private DataAdapters.DirectoriesTableAdapter adapter;
        private DataBase.MovieDataSet.DirectoriesDataTable table;
        private Regex reg;
        private BackgroundWorker scanWorker;

        private List<string> FilePaths
        {
            get;
            set;
        }

        public List<string> FileExtensions
        {
            get;
            set;
        }

        public delegate void ScanCompletedEventHandler(List<string> filePaths);

        public event ScanCompletedEventHandler ScanCompleted;

        public Scanner()
        {
            FilePaths = new List<string>();
            FileExtensions = new List<string>() { ".mkv", ".avi", ".mts", ".mpg", ".mpeg", ".mov", ".h264" };
            reg = new Regex("S[0-9]?[0-9]E[0-9]?[0-9]");
            scanWorker = new BackgroundWorker();

            scanWorker.DoWork += new DoWorkEventHandler(scanWorker_DoWork);
            scanWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(scanWorker_RunWorkerCompleted);

        }

        private void scanWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ScanCompleted(FilePaths);
        }

        private void scanWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            adapter = new DataAdapters.DirectoriesTableAdapter();
            table = adapter.GetData();
            Scan();
            //e.Result = FilePaths;
        }

        public void StartScanning()
        {
            scanWorker.RunWorkerAsync();
        }

        private void Scan()
        {
            var dirs = from d in table select d;

            Parallel.ForEach(dirs, (dir) =>
            {
                ProcessDir(dir.path, 0, 4, FileExtensions);
            });
        }

        private bool IsSystemDirectory(string path)
        {
            if (path.Contains("System"))
            {
                return true;
            }
            return false;
        }

        private bool IsMovieFile(string path)
        {
            if (reg.Match(path).Success)
            {
                return false;
            }
            return true;
        }

        private void ProcessDir(string sourceDir, int recursionLvl, int HowDeepToScan, List<string> fileExtHit)
        {
            if (recursionLvl <= HowDeepToScan)
            {
                if (IsSystemDirectory(sourceDir))
                {
                    return;
                }

                // Process the list of files found in the directory and select any file that ends with the list of extensions and passes the IsMovieFile
                var list = from m in Directory.GetFiles(sourceDir)
                           where FileExtensions.Any(val => m.Substring(m.Length - 3).Contains(val))
                           && IsMovieFile(m) == false
                           select m;

                foreach (string file in list)
                {
                    FilePaths.Add(file);
                }

                // Recurse into subdirectories of this directory.
                string[] subdirEntries = Directory.GetDirectories(sourceDir);
                foreach (string subdir in subdirEntries)
                {
                    // Do not iterate through reparse points
                    if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
                    {
                        ProcessDir(subdir, recursionLvl + 1, HowDeepToScan, fileExtHit);
                    }
                }
            }
        }
    }
}
